<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%> 
<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" Inherits="System.Web.UI.Page" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.Administration" %>
<%@ Import Namespace="System.Text.RegularExpressions" %>
<%@ Import Namespace="System.Web" %>

<script runat="server">
/* 
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

    
    private const string webAppPropertyKey = "Custom404Path";
    private const string webAppPropertyForGuid = "URLRedirectListGuid";

    protected override void OnPreInit(EventArgs e)
    {
        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            using (SPSite thisSite = new SPSite(SPContext.Current.Site.Url))
            {
                SPWebApplication webApp = thisSite.WebApplication;
                using (SPWeb urlRedirectWeb = webApp.Sites[0].RootWeb)
                {
                    this.Page.MasterPageFile = urlRedirectWeb.MasterUrl;
                }
            }
        });
        base.OnPreInit(e);
    }
    protected override void OnPreRender(EventArgs e)
    {
        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            using (SPSite thisSite = new SPSite(SPContext.Current.Site.Url))
            {
                SPWebApplication webApp = thisSite.WebApplication;
                using (SPWeb urlRedirectWeb = webApp.Sites[0].RootWeb)
                {

                    string custom404Path = "";

                    string pageNotFound = Request.QueryString.ToString();
                    pageNotFound = Page.Server.UrlDecode(pageNotFound);
                    pageNotFound = pageNotFound.Replace("404;", "");

                    if (webApp.Properties.ContainsKey(webAppPropertyKey))
                    {
                        custom404Path = (string)webApp.Properties[webAppPropertyKey];
                    }

                    if ((custom404Path != "") && !(custom404Path.ToLower().Contains("custom404handler.aspx")) && !(pageNotFound.ToLower().Contains(custom404Path.ToLower())))
                    {

                        if (webApp.Properties.ContainsKey(webAppPropertyForGuid))
                        {
                            // Lets start finding the URL Redirect list
                            try
                            {
                                SPList tryUrlRedirectList = urlRedirectWeb.Lists[new Guid(webApp.Properties[webAppPropertyForGuid].ToString())];
                            }
                            catch (Exception ex)
                            {
                                lblMessage.Text = "<span style=\"color: red; font-weight: bold;\">While the &quot;List Based 404 Handler&quot; Feature appears to have been Activated on this web application, there was a problem finding the <em>URL Redirect</em> (GUID: [" + webApp.Properties[webAppPropertyForGuid].ToString() + ") list in the [" + urlRedirectWeb.Url + "] web. Your Administrator could try re-activating the feature. Error: " + ex.Message + "</span>";
                                return;
                            }

                            SPList urlRedirectList = urlRedirectWeb.Lists[new Guid(webApp.Properties[webAppPropertyForGuid].ToString())];

                            SPQuery urlItemQuery = new SPQuery();
                            urlItemQuery.Query = "<Where>"
                                + "<Or>"
                                    + "<Eq><FieldRef Name='Disable'/><Value Type='Boolean'>FALSE</Value></Eq>"
                                    + "<IsNull><FieldRef Name='Disable'/></IsNull>"
                                + "</Or>"
                                + "</Where>"
                                + "<OrderBy>"
                                    + "<FieldRef Name='Sorting' Ascending='TRUE' />"
                                +"</OrderBy>";


                            SPListItemCollection potentialUrls = urlRedirectList.GetItems(urlItemQuery);
                            
                            
                            foreach (SPListItem thisItem in potentialUrls)
                            {
                                
                                bool useRegularExpressions = false;

                                if (thisItem.Fields.ContainsField("UseRegularExpressions")) useRegularExpressions = (bool)thisItem["UseRegularExpressions"];
                                
                                string thisPattern = "";
                                if (!useRegularExpressions)
                                    thisPattern = "^" + thisItem["URL"].ToString().Replace(".", @"\.").Replace("*", ".*") + "$";
                                else
                                    thisPattern = thisItem["URL"].ToString();
                                    

                                if (Regex.IsMatch(pageNotFound, thisPattern))
                                {

                                    string redirectUrl = "";
                                    string displayMessage = "";
                                    string displayPageTitle = "";
                                    string displayTitleArea = "";

                                    if (thisItem.Fields.ContainsField("RedirectURL")) redirectUrl = (string)thisItem["RedirectURL"];
                                    if (thisItem.Fields.ContainsField("DisplayMessage")) displayMessage = thisItem["DisplayMessage"].ToString();
                                    if (thisItem.Fields.ContainsField("DisplayPageTitle")) displayPageTitle = (string)thisItem["DisplayPageTitle"];
                                    if (thisItem.Fields.ContainsField("DisplayTitleArea")) displayTitleArea = (string)thisItem["DisplayTitleArea"];

                                    string cleanedDisplayMessage = Regex.Replace(displayMessage, @"<(.|\n)+?>", "").Trim();

                                    if (redirectUrl != null && redirectUrl != "")
                                    {
                                        if (useRegularExpressions)
                                            redirectUrl = Regex.Replace(pageNotFound, thisPattern, redirectUrl);
                                        Response.Redirect(redirectUrl);
                                    }
                                    else
                                    {
                                        if (cleanedDisplayMessage != null) litPageContents.Text = displayMessage;
                                        if (displayPageTitle != null) litPageTitle.Text = displayPageTitle;
                                        if (displayTitleArea != null) litTitleArea.Text = displayTitleArea;
                                    }
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // Otherwise, just redirect to the page specified in the web application's properties.
                            Response.Redirect(custom404Path);
                        }
                    }
                }
            }
        });
    }

</script>
<asp:Content ID="Main" runat="server" contentplaceholderid="PlaceHolderMain" >
    <asp:Literal ID="litPageContents" runat="server" Text="<p>The page you are trying to reach cannot be found.</p>" />
    <asp:Label ID="lblMessage" runat="server" />
</asp:Content>

<asp:Content ID="PageTitle" runat="server" contentplaceholderid="PlaceHolderPageTitle" >
  <asp:Literal ID="litPageTitle" runat="server" Text="404 - Page Not Found" />
</asp:Content>

<asp:Content ID="PageTitleInTitleArea" runat="server" contentplaceholderid="PlaceHolderPageTitleInTitleArea" >
  <asp:Literal ID="litTitleArea" runat="server" Text="404 - Page Not Found" />
</asp:Content>